// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Y [author] rhyme_lph
// s [email]  rhymelph@gmail.com
// D [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/app_spaces.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/invoice_entity.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/utils/form_utils.dart';
import 'package:finance_app/src/utils/permission_utils.dart';
import 'package:finance_app/src/utils/reg_exp_utils.dart';
import 'package:finance_app/src/widgets/button/add_button.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_button.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_white_button.dart';
import 'package:finance_app/src/widgets/list_item/list_header_item.dart';
import 'package:finance_app/src/widgets/common_app_bar.dart';
import 'package:finance_app/src/widgets/input/search_input_field.dart';
import 'package:finance_app/src/widgets/select/invoice_number_check_box.dart';
import 'package:finance_app/src/widgets/wrapper/normal_form_wrapper.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/provider/dashboard/invoice/invoice_number_provider.dart';
import 'package:finance_app/src/router_gen/router_meta.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:tuple/tuple.dart';

export 'package:finance_app/src/entities/invoice_entity.dart';

@RouterMeta(paramName: "invoiceNumberPage")
class InvoiceNumberPage extends StatefulWidget {
  final InvoiceEntity select;
  final List<InvoiceEntity> selects;
  final bool isMultiple;
  final int filterIssueTo;

  const InvoiceNumberPage(
      {Key key, this.select, this.selects, this.isMultiple, this.filterIssueTo})
      : super(key: key);

  @override
  _InvoiceNumberPageState createState() => _InvoiceNumberPageState();
}

class _InvoiceNumberPageState extends State<InvoiceNumberPage>
    with PagePresenter<InvoiceNumberPage, InvoiceNumberProvider> {
  @override
  void initState() {
    provider.filterIssueTo = widget.filterIssueTo;
    provider.invoice = widget.select;
    provider.invoices = widget.selects ?? [];
    provider.isMultiple = widget.isMultiple ?? false;
    super.initState();
  }

  @override
  PreferredSizeWidget get appBar => getDefaultAppBar(
        title: S.current.invoice_number,
      );

  @override
  Widget get buildEmptyWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              children: [
                _buildTopWidget(),
                Expanded(
                  child: super.buildEmptyWidget,
                ),
              ],
            ),
            if (provider.isMultiple == true)
              Positioned(
                  bottom: getDp(32) + MediaQuery.of(context).padding.bottom,
                  left: 0.0,
                  right: 0.0,
                  child: _buildBottomBar()),
          ],
        ),
      );

  @override
  Widget get buildWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _buildTopWidget(),
                Expanded(
                  child: listBuilder<String>(
                    selector: (_, __) => __.searchController.text,
                    builder:
                        (BuildContext context, String value, Widget child) {
                      List<Widget> childList = buildChildList(value);
                      return childList.isEmpty
                          ? super.buildEmptyWidget
                          : SmartRefresher(
                              controller: provider.refreshController,
                              onRefresh: provider.onRefresh,
                              onLoading: provider.onLoadMore,
                              enablePullUp: provider.hasUp,
                              child: ListView(
                                children: childList,
                              ),
                            );
                    },
                  ),
                ),
              ],
            ),
            Positioned(
                bottom: getDp(32) + MediaQuery.of(context).padding.bottom,
                left: 0.0,
                right: 0.0,
                child: _buildBottomBar()),
          ],
        ),
      );

  Widget _buildBottomBar() => Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          NormalFloatTextWhiteButton(
            title: S.current.cancel,
            onTap: provider.onCancel,
          ),
          SizedBox(
            width: getDp(15),
          ),
          NormalFloatTextButton(
            title: S.current.done,
            onTap: provider.onDone,
          ),
        ],
      );

  List<Widget> buildChildList(String value) {
    return provider.data.toList().map((e) => buildSliverItem(e)).toList();
  }

  Widget buildSliverItem(InvoiceEntity data) {
    return listBuilder<Tuple2<InvoiceEntity, bool>>(
      selector: (_, __) => Tuple2(
          data,
          __.isMultiple == true
              ? __.invoices.firstWhere((element) => element.id == data.id,
                      orElse: () => null) !=
                  null
              : __.invoice?.id == data.id),
      builder: (BuildContext context, Tuple2<InvoiceEntity, bool> value,
              Widget child) =>
          PressedOpacityButton(
        onPressed: () => provider.onSelect(value.item1),
        child: provider.isMultiple
            ? InvoiceNumberCheckBox(
                title: value.item1?.contact?.name ?? '',
                billNumber: value.item1.number,
                due: DateTimeUtils.formatDateTimeString(value.item1.dueAt),
                amount: value.item1.total.toDouble(),
                unit: value.item1.currencyCode,
                isSelect: value.item2,
                status:
                    value.item1.isOverdue == 1 && value.item1.status == 'open'
                        ? 'Overdue'
                        : FormUtils.getStatus(ReimburseModel.invoice,
                            value.item1.status, value.item1.unpaid),
              )
            : InvoiceNumberRadio(
                title: value.item1?.contact?.name ?? '',
                billNumber: value.item1.number,
                due: DateTimeUtils.formatDateTimeString(value.item1.dueAt),
                amount: value.item1.total.toDouble(),
                unit: value.item1.currencyCode,
                isSelect: value.item2,
                status:
                    value.item1.isOverdue == 1 && value.item1.status == 'open'
                        ? 'Overdue'
                        : FormUtils.getStatus(ReimburseModel.invoice,
                            value.item1.status, value.item1.unpaid),
              ),
      ),
    );
  }

  Widget buildSliverHeader({String title}) {
    final String _title = title.isEmpty ? "*" : title;
    return ListHeaderItem(
      title: _title,
    );
  }

  Widget _buildTopWidget() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(
          height: getDp(20),
        ),
        SearchInputField(
          controller: provider.searchController,
          focusNode: provider.searchFocusNode,
        ),
        Config.hasPermission(PermissionUtils.invoice)
            ? Column(
                children: [
                  NormalFormWrapper(
                    child: AddButton(
                      title: S.current.add_invoice,
                      onTap: provider.onNavAddInvoice,
                    ),
                  ),
                  AppSpaces.grayH05,
                ],
              )
            : AppSpaces.h20,
      ],
    );
  }

  bool _onSearchInputGroup(InvoiceEntity element) {
    String searchInput = provider.searchController.text;
    return RegExpUtils.getSearchRegExp(searchInput)
        .hasMatch(element.contact.name);
  }
}
